home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Ham Radio 2000
/
Ham Radio 2000.iso
/
ham2000
/
qex
/
qexsndcd
/
cw250.cpp
next >
Wrap
Text File
|
1994-07-06
|
7KB
|
186 lines
// --------------------------------------------------------------------
// Super Duper DSP CW filter - Control and User Interface
// Demo software accompanying the QEX August 1994 article:
// "Programming a DSP PC Sound Card for Amateur Radio"
// (c) Johan Forrer, KC7WW
// 26553 Priceview Drive
// Monroe, OR 97456
// --------------------------------------------------------------------
//
// Compilation/link instructions for Borland C++ 4.0
// >bcc -c -ml -O2 -Z -G cw250.cpp
// >tlink /x c:\bc4\lib\c0l cw250 PSA1.obj PSA2.obj, emu mathl cl
//
// --------------------------------------------------------------------
// This is how the AD1848 is reprogrammed:
// --------------------------------------------------------------------
// Idx=0
// Sta=0
// 0 =47 select left line, gain =7
// 1 =47 select right line, gain =7
// 2 =0x80 mute left aux#1
// 3 =0x80 mute right aux#1
// 4 =0x80 mute left aux#2
// 5 =0x80 mute right aux#2
// 6 =0x07 left DAC with some attenuation
// 7 =0x07 right DAC with some attenuation
// 8 =0x51 16 bit 2s compl, linear PCM, stereo,
// xtal1=16.93MHz, 5512.5 kHz,
// 9 =0x08 DMA capture/playback, Autocalibrate after mode change,
// disable capture/playback, dual DMA mode
// 10 =0 N.A
// 11 =0 N.A
// 12 =0 N.A
// 13 =0 digital mix muted
// 14 =0 base count = 0
// 15 =0 base count = 0
// --------------------------------------------------------------------
#include "psa.h"
// --------------------------------------------------------------------
// Local function prototypes
// --------------------------------------------------------------------
void start_application(char *, unsigned char *);
void terminate_application(void);
void timer_test(void);
int tick; // a global tick counter
#define MON "cwmon.ld" // define name of bootstrap
#define APP "cw250.cde" // define name of application
void main()
{
unsigned int boot_version;
unsigned char initstate[18]={0,0,0x47,0x47,0x80,0x80,0x80,
0x80,0x07,0x07,0x51,0x08,0,0,0,0,0,0};
// -------------------------------------------------------------------------
// Announce who we are and what the program is about
// -------------------------------------------------------------------------
printf("Demo program to set up and communicate with a PSA sound card\n");
printf("By Johan Forrer, KC7WW\n\n");
// -------------------------------------------------------------------------
// Check for presence and initialze DSP card
// -------------------------------------------------------------------------
if (!checkDSPcard(pssbase, wssbase)) {
printf("No PSA card - or WSS address is not available\n");
exit(0);
}
// -------------------------------------------------------------------------
// Perform the DSP bootstrap next
// and verify that it has completed successfully
// -------------------------------------------------------------------------
boot_version=bootdsp(MON, NULL, (unsigned)16000);
checkdsptestprog();
printf("Monitor version %d.%d reported\n",
boot_version>>8, boot_version&0x0F);
// -------------------------------------------------------------------------
// Finally we are ready to load and run the DSP application
// also start the timer
// -------------------------------------------------------------------------
start_application(APP, initstate);
timer_test();
terminate_application();
}
//---------------------------------------------------------------------------
// Some local functions
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
// Start application
//---------------------------------------------------------------------------
void start_application(char *app_name, unsigned char ad1848_state[])
{
load_DSP_mem(app_name); // load the DSP application code
set1848state(ad1848_state); // reprogram CODEC
outp(wssbase+WSS_CODECINDEXADDR,0x0009); // Capture/Playback on
outp(wssbase+WSS_CODECINDEXDATA,0x0003);
putdspword(0x00b4); // send "start application" code to DSP
}
//---------------------------------------------------------------------------
// Terminate application
//---------------------------------------------------------------------------
void terminate_application()
{
putdspword(0x00b5); // send "stop application" code to DSP
outp(wssbase+WSS_CODECINDEXDATA,0x0009); // Playback/capture off
outp(wssbase+WSS_CODECINDEXDATA, 0);
outp(wssbase+WSS_CODECINDEXADDR,0x0006); // mute DAC
outp(wssbase+WSS_CODECINDEXDATA, 0xDF);
outp(wssbase+WSS_CODECINDEXADDR,0x0007);
outp(wssbase+WSS_CODECINDEXDATA, 0xDF);
}
//--------------------------------------------------------------------------
// Timer test using interrupt IRQ7
//--------------------------------------------------------------------------
void timer_test()
{
// Define ISR prototypes
void interrupt (*oldfunc)(...); // for storage of old vector
void interrupt DSP_int_serv(...); // Prototype for new interrupt serv.
unsigned char old_IMR; // Save old PIC IMR
tick=0;
printf("Timer is now ticking - hit any key to stop application\n ");
oldfunc=getvect(INT); // Hook IRQ7 on the PC side
setvect(INT,DSP_int_serv);
// Set INT7 on DSP side as well
outpw(pssbase+PSS_CONFIG,IRQ7);
old_IMR=inp(0x21); // get IMR
outp(0x21,old_IMR&0x7F); // Arm PC's IRQ7 in IMR
putdspword(0x00b0); // send "start timer" code to DSP
// Show timer ticks, check when user quits
for(;;) {
if(kbhit()) break;
if(tick) {
printf(".");
tick=0;
}
}
getch(); // flush out breakout charater
putdspword(0x00b1); // send "stop timer" code to DSP
outpw(pssbase+PSS_IRQ_ACK, 0); // Clear any pending PSA interrupts
outpw(pssbase+PSS_CONFIG,0x0000); // Remove PSA from IRQ7
outp(0x21,old_IMR); // Restore IMR
setvect(INT, oldfunc); // Restore INT
printf("\nApplication terminated\n");
}
//--------------------------------------------------------------------------
// The new IRQ7 interrupt handler
//--------------------------------------------------------------------------
void interrupt DSP_int_serv(...)
{
outpw(pssbase+PSS_IRQ_ACK, 0); // Clear the interrupt
outp(0x20,0x20); // write EOI to PIC
// else bad things happen!
tick++;
}